home *** CD-ROM | disk | FTP | other *** search
/ Aminet 37 / Aminet 37 (2000)(Schatztruhe)[!][Jun 2000].iso / Aminet / dev / lang / sofa.lha / sofa / smalleiffel / lib_se / position.e < prev    next >
Text File  |  2000-03-25  |  9KB  |  282 lines

  1. --          This file is part of SmallEiffel The GNU Eiffel Compiler.
  2. --          Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
  3. --            Dominique COLNET and Suzanne COLLIN - colnet@loria.fr
  4. --                       http://SmallEiffel.loria.fr
  5. -- SmallEiffel is  free  software;  you can  redistribute it and/or modify it
  6. -- under the terms of the GNU General Public License as published by the Free
  7. -- Software  Foundation;  either  version  2, or (at your option)  any  later
  8. -- version. SmallEiffel is distributed in the hope that it will be useful,but
  9. -- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10. -- or  FITNESS FOR A PARTICULAR PURPOSE.   See the GNU General Public License
  11. -- for  more  details.  You  should  have  received a copy of the GNU General
  12. -- Public  License  along  with  SmallEiffel;  see the file COPYING.  If not,
  13. -- write to the  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  14. -- Boston, MA 02111-1307, USA.
  15. --
  16. expanded class POSITION
  17.    --
  18.    -- A position in some source file (ie. an Eiffel source text file 
  19.    -- or some -cecil file)..
  20.    --
  21.  
  22. inherit GLOBALS;
  23.  
  24. feature
  25.  
  26.    base_class: BASE_CLASS;
  27.          -- The corresponding one which may be Void for example when
  28.          -- `is_unknown' or when parsing a -cecil file.
  29.  
  30.    line: INTEGER is
  31.          -- The corresponding `line' number in the source file or 0 
  32.          -- when `is_unknown'.
  33.       local
  34.          bit: BIT Integer_bits;
  35.       do
  36.          if mangling.last then
  37.             bit := mangling @>> 1;
  38.             bit := bit and 111111111111111B; 
  39.          else
  40.             bit := mangling @>> 8;
  41.             bit := bit and 1111111111111B;
  42.          end;
  43.          Result := bit.to_integer;
  44.       ensure
  45.          not is_unknown implies Result >= 0
  46.       end;
  47.    
  48.    column: INTEGER is
  49.          -- The `column' number in the source file or 0 when `is_unknown' or 
  50.          -- when there is not enough space in `mangling' for the `column'.
  51.       local
  52.          bit: BIT Integer_bits;
  53.       do
  54.          if mangling.last then
  55.             -- Result is 0 because `column' is not memorized.
  56.          else
  57.             bit := mangling @>> 1; -- To drop the flag.
  58.             bit := bit and 1111111B; 
  59.             Result := bit.to_integer;
  60.          end;
  61.       ensure
  62.          Result >= 0
  63.       end;
  64.    
  65.    base_class_name: CLASS_NAME is
  66.          -- The corresponding one when already loaded by the `eiffel_parser'.
  67.       local
  68.          bc: BASE_CLASS;
  69.       do
  70.          bc := base_class;
  71.          if bc /= Void then
  72.             Result := bc.name;
  73.          end;
  74.       end;
  75.  
  76.    path: STRING is
  77.          -- The corresponding file `path' or Void when `is_unknown'.
  78.       local
  79.          bc: BASE_CLASS;
  80.          id_value: INTEGER;
  81.       do
  82.          bc := base_class;
  83.          if bc /= Void then
  84.             Result := bc.path;
  85.          end;
  86.          if Result = Void then
  87.             -- Looking for the path of the -cecil file.
  88.             id_value := id;
  89.             if id /= 0 then
  90.                Result := id_provider.alias_of(id);
  91.             end;
  92.          end;
  93.       ensure
  94.          Result /= Void implies string_aliaser.item(Result) = Result
  95.       end;
  96.  
  97.    is_unknown: BOOLEAN is
  98.          -- True when the `eiffel_parser' as called `set'.
  99.       do
  100.          Result := mangling.to_integer = 0;
  101.       end;
  102.  
  103.    before(other: like Current): BOOLEAN is
  104.          -- Is `Current' position strictly before `other' (which is in the 
  105.          -- same source text file).
  106.       require
  107.          path = other.path
  108.       local
  109.          li, other_li: INTEGER;
  110.       do
  111.          li := line;
  112.          other_li := other.line;
  113.          if li < other_li then
  114.             Result := true;
  115.          elseif li = other_li then
  116.             Result := column < other.column;
  117.          end;
  118.       end;
  119.  
  120.    show is
  121.       local
  122.          li, co, nb: INTEGER;
  123.          bc: BASE_CLASS;
  124.          bcn: CLASS_NAME;
  125.          name, file_path, the_line: STRING;
  126.       do
  127.          li := line;
  128.          co := column;
  129.          bc := base_class;
  130.          if bc /= Void then
  131.             check id = bc.id end;
  132.             bcn := base_class_name;
  133.          end;
  134.          if bcn /= Void then
  135.             name := bcn.to_string;
  136.             file_path := bc.path;
  137.          end;
  138.          echo.w_put_string("Line ");
  139.          echo.w_put_integer(li);
  140.          if co > 0 then
  141.             echo.w_put_string(" column ");
  142.             echo.w_put_integer(co);
  143.          end;
  144.          echo.w_put_string(" in ");
  145.          if name /= Void then
  146.             echo.w_put_string(name);
  147.          end;
  148.          if file_path /= Void then
  149.             echo.w_put_string(" (");
  150.             echo.w_put_string(file_path);
  151.             echo.w_put_character(')');
  152.          end;
  153.          echo.w_put_string(" :%N");
  154.          if file_path /= Void then
  155.             the_line := get_line(file_path,li);
  156.             if li > 0 and then the_line /= Void then
  157.                echo.w_put_string(the_line);
  158.                echo.w_put_character('%N');
  159.                if co > 0 then
  160.                   from
  161.                      nb := 1;
  162.                   until
  163.                      nb >= co
  164.                   loop
  165.                      if the_line.item(nb) = '%T' then
  166.                         echo.w_put_character('%T');
  167.                      else
  168.                         echo.w_put_character(' ');
  169.                      end;
  170.                      nb := nb + 1;
  171.                   end;
  172.                   echo.w_put_string("^%N");
  173.                end;
  174.             end;
  175.          end;
  176.       end;
  177.  
  178.    append_in(buffer: STRING) is
  179.       require
  180.          buffer /= Void
  181.       local
  182.          li, co: INTEGER;
  183.          bc: BASE_CLASS;
  184.          bcn: CLASS_NAME;
  185.          place: STRING;
  186.       do
  187.          li := line;
  188.          co := column;
  189.          buffer.append("Line ");
  190.          li.append_in(buffer);
  191.          if co > 0 then
  192.             buffer.append(" column ");
  193.             co.append_in(buffer);
  194.          end;
  195.          bc := base_class;
  196.          if bc /= Void then
  197.             place := bc.path;
  198.             if place = Void then
  199.                bcn := bc.name;
  200.                if bcn /= Void then
  201.                   place := bcn.to_string;
  202.                end;
  203.             end;
  204.             if place /= Void then
  205.                buffer.append(" in %"");
  206.                buffer.append(place);
  207.                buffer.append(fz_03);
  208.             end;
  209.          end;
  210.       end;
  211.    
  212. feature {EIFFEL_PARSER}
  213.    
  214.    set(li, co, class_id: INTEGER; bc: like base_class) is
  215.       require
  216.          li >= 1;
  217.          co >= 1;
  218.          class_id >= 0
  219.       do
  220.          base_class := bc;
  221.          check Integer_bits >= 32 end;
  222.          if class_id <= 2047 and then li <= 8191 and then co <= 127 then
  223.             mangling := (class_id.to_bit @<< 21);       -- 11 bits for `id'
  224.             mangling := mangling or (li.to_bit @<< 8);  -- 13 bits for `line'
  225.             mangling := mangling or (co.to_bit @<< 1);  -- 7  bits for `column'
  226.          else
  227.             -- The `column' is not memorized.
  228.             mangling := (class_id.to_bit @<< 17);       -- 15 bits for `id'
  229.             mangling := mangling or (li.to_bit @<< 1);  -- 16 bits for `line'
  230.             mangling := mangling or (1).to_bit;         -- forget `column'.
  231.          end;
  232.       ensure
  233.          line = li;
  234.          id = class_id;
  235.          column = 0 or else column = co;
  236.       end;
  237.  
  238. feature {C_PRETTY_PRINTER}
  239.  
  240.    mangling: BIT Integer_bits;
  241.          -- In order to save memory (there are a lot of objects like `Current'), 
  242.          -- the `id' of the class, the `line' and the `column' are saved in this 
  243.          -- BIT sequence. Two mangling are used, and the `column' may be 
  244.          -- dropped (not memorized, see `set'). This implementation assume 
  245.          -- that `Integer_bits' is greater or equal to 32.
  246.    
  247. feature {NONE}
  248.  
  249.    id: INTEGER is
  250.       do
  251.          if mangling.last then
  252.             Result := (mangling @>> 17).to_integer; 
  253.          else
  254.             Result := (mangling @>> 21).to_integer; 
  255.          end;
  256.       ensure
  257.          Result >= 0
  258.       end;
  259.    
  260.    get_line(file_path: STRING; li: INTEGER): STRING is
  261.       require
  262.          not file_path.is_empty;
  263.          li > 0
  264.       local
  265.          i: INTEGER;
  266.       do
  267.          echo.sfr_connect(tmp_file_read,file_path);
  268.          if tmp_file_read.is_connected then
  269.             from until tmp_file_read.end_of_input or else i = li
  270.             loop
  271.                tmp_file_read.read_line;
  272.                i := i + 1;
  273.             end;
  274.             if not tmp_file_read.end_of_input then
  275.                Result := tmp_file_read.last_string;
  276.             end;
  277.             tmp_file_read.disconnect;
  278.          end;
  279.       end;
  280.  
  281. end -- POSITION
  282.